package format

import (
	"encoding/json"
	"fmt"

	"peilian-api/app/global/log"

	"net/http"

	"github.com/gin-gonic/gin"
)

type Res struct {
	Code  int         `json:"code"`
	Total int         `json:"total"`
	Data  interface{} `json:"data"`
	Msg   string      `json:"msg"`
}

type ResJson struct {
	Code int         `json:"code"`
	Data interface{} `json:"data"`
	Msg  string      `json:"msg"`
}

func NewResponseJson(ctx *gin.Context) *responseJson {
	return &responseJson{
		context: ctx,
		uri:     ctx.Request.RequestURI,
	}
}

type responseJson struct {
	context *gin.Context
	uri     string
}

func (r *responseJson) SetHeader(key, value string) *responseJson {
	r.context.Writer.Header().Set(key, value)
	return r
}

// {}
func (r *responseJson) Success(data []interface{}) {
	log.Logger.InfoF(r.context, fmt.Sprintf("info: %+v", data))
	r.context.JSON(http.StatusOK, Res{
		Code: http.StatusOK,
		Data: data,
		Msg:  "OK",
	})
}

// []
func (r *responseJson) SuccessDataList(count int, data ...interface{}) {
	log.Logger.InfoF(r.context, fmt.Sprintf("count:%d, info: %+v", count, data))
	if count == 0 {
		r.context.JSON(http.StatusOK, Res{
			Code:  http.StatusOK,
			Total: 0,
			Data:  make([]interface{}, 0),
			Msg:   "OK",
		})
	} else {
		r.context.JSON(http.StatusOK, Res{
			Code:  http.StatusOK,
			Total: count,
			Data:  data[0],
			Msg:   "OK",
		})
	}
}

// params
func (r *responseJson) SuccessJson(params ...interface{}) {
	b, _ := json.Marshal(params)
	log.Logger.InfoF(r.context, string(b))
	r.context.JSON(http.StatusOK, gin.H{
		"code": http.StatusOK,
		"data": params,
		"msg":  "OK",
	})
}

// {}
func (r *responseJson) SuccessObj(params ...interface{}) {
	b, _ := json.Marshal(params)
	log.Logger.InfoF(r.context, string(b))
	r.context.JSON(http.StatusOK, gin.H{
		"code": http.StatusOK,
		"data": params[0],
		"msg":  "OK",
	})
}

// []
func (r *responseJson) Error(errorCode int, params ...interface{}) {
	log.Logger.InfoF(r.context, fmt.Sprintf("code:%d, %+v", errorCode, params))
	result := Res{
		Code: errorCode,
		Data: make([]interface{}, 0),
		Msg:  "",
	}
	r.context.Abort()
	r.context.JSON(http.StatusOK, result)
}

// []
func (r *responseJson) Err(errorCode int, msg string, params ...interface{}) {
	log.Logger.InfoF(r.context, fmt.Sprintf("code:%d, msg:%s, info: %+v", errorCode, msg, params))
	result := Res{
		Code: errorCode,
		Data: make([]interface{}, 0),
		Msg:  msg,
	}
	r.context.Abort()
	r.context.JSON(http.StatusOK, result)
}

// {}
func (r *responseJson) ErrObj(errorCode int, msg string, params ...interface{}) {
	log.Logger.InfoF(r.context, fmt.Sprintf("code:%d, msg:%s, info: %+v", errorCode, msg, params))
	result := Res{
		Code: errorCode,
		Data: struct{}{},
		Msg:  msg,
	}
	r.context.Abort()
	r.context.JSON(http.StatusOK, result)
}

// 返回成功并发送消息 |----------***********----------|
// []
func (r *responseJson) SuccessDataListMsg(errorCode int, msg string) {
	msgInfo := fmt.Sprintf("uri: %s, errorCode:%d, msg: %+v", r.uri, errorCode, msg)
	log.Logger.ErrorMsgF(r.context, msgInfo)
	r.context.JSON(http.StatusOK, Res{
		Code:  http.StatusOK,
		Total: 0,
		Data:  make([]interface{}, 0),
		Msg:   "OK",
	})

}

// {}
func (r *responseJson) SuccessObjMsg(errorCode int, msg string) {
	msgInfo := fmt.Sprintf("errorCode:%d, msg:%s", errorCode, msg)
	log.Logger.ErrorMsgF(r.context, msgInfo)
	result := Res{
		Code: http.StatusOK,
		Data: struct{}{},
		Msg:  msg,
	}
	r.context.Abort()
	r.context.JSON(http.StatusOK, result)
}
